package com.gateway.router.resilience4j.builder;

import com.gateway.common.dto.convert.rule.Resilience4JHandle;
import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig;
import io.github.resilience4j.core.IntervalFunction;
import io.github.resilience4j.timelimiter.TimeLimiterConfig;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;

import java.time.Duration;

/**
 * @program: api-gateway
 * @description:
 * @author: YuKai Fan
 * @create: 2025/2/25 09:42
 **/
public final class Resilience4JBuilder {

    private Resilience4JBuilder() {
    }

    /**
     * 构建 CircuitBreakerConfig
     * @param handle
     * @return
     */
    public static Pair<CircuitBreakerConfig, TimeLimiterConfig> build(Resilience4JHandle handle) {
        handle.checkData(handle);
        CircuitBreakerConfig circuitBreakerConfig = CircuitBreakerConfig.custom()
                .recordExceptions(Throwable.class, Exception.class)
                .failureRateThreshold(handle.getFailureRateThreshold())
                .automaticTransitionFromOpenToHalfOpenEnabled(handle.getAutomaticTransitionFromOpenToHalfOpenEnabled())
                .slidingWindow(handle.getSlidingWindowSize(), handle.getMinimumNumberOfCalls(),
                        handle.getSlidingWindowType() == 0
                                ? CircuitBreakerConfig.SlidingWindowType.COUNT_BASED
                                : CircuitBreakerConfig.SlidingWindowType.TIME_BASED).waitIntervalFunctionInOpenState(IntervalFunction
                        .of(Duration.ofMillis(handle.getWaitIntervalFunctionInOpenState())))
                .permittedNumberOfCallsInHalfOpenState(handle.getPermittedNumberOfCallsInHalfOpenState()).build();

        TimeLimiterConfig timeLimiterConfig = TimeLimiterConfig.custom()
                .timeoutDuration(Duration.ofMillis(handle.getTimeoutDuration())).build();

        return ImmutablePair.of(circuitBreakerConfig, timeLimiterConfig);
    }
}
